#include "MemoryPool.h"

int main()
{
    MemoryPool<int> intPool(11);
    std::cout << "intPool located: " << &intPool << std::endl;
    for (size_t i = 0; i < 5; i++)
    {

        int *num1 = intPool.allocate();
        // occupy 16B.
        std::cout << "num1 located: " << num1 << std::endl;
        *num1 = 22;
        std::cout << *num1 << std::endl;

        int *num2 = intPool.allocate();
        std::cout << "num2 located: " << num2 << std::endl;
        *num2 = 33;
        std::cout << *num2 << std::endl;

        intPool.deallocate(num1);
        intPool.deallocate(num2);
    }

    MemoryPool<std::string> stringPool(10);
    std::string *str1 = stringPool.allocate();
    *str1 = "hello";
    std::cout << *str1 << std::endl;

    std::string *str2 = stringPool.allocate();
    *str2 = "world";
    std::cout << *str2 << std::endl;

    stringPool.deallocate(str1);
    stringPool.deallocate(str2);

    class Worker
    {
    private:
        std::string name;
        int age;

    public:
        void setName(std::string m_name)
        {
            this->name = m_name;
        }
        std::string getName()
        {
            return this->name;
        }

        void setAge(int m_Age)
        {
            this->age = m_Age;
        }
        int getAge()
        {
            return this->age;
        }
        void doWork()
        {
            int m = 5;
            while (m--)
            {
                std::cout << this->getName() + " is working" << std::endl;
            }
        }
    };

    ObjectMemoryPool<Worker> workerPool;

    for (size_t i = 0; i < 5; i++)
    {
        Worker *worker1 = workerPool.allocate();
        std::cout << "worker1 located: " << worker1 << std::endl;
        worker1->setAge(22);
        worker1->setName("buleWorkBuff");
        std::cout << "worker1's name is: " << worker1->getName() << " and age is: " << worker1->getAge() << std::endl;

        worker1->doWork();

        Worker *worker2 = workerPool.allocate();
        std::cout << "worker2 located: " << worker2 << std::endl;
        worker1->setAge(22);
        worker2->setAge(22);
        worker2->setName("redWorkBuff");
        std::cout << "worker2's name is: " << worker2->getName() << " and age is: " << worker2->getAge() << std::endl;

        worker2->doWork();

        workerPool.deallocate(worker1);
        workerPool.deallocate(worker2);
    }

    return 0;
}
